using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using Magiq.Support;
using Magiq.Support.Database;
using Magiq.Support.DynamicClasses;
using Magiq.Update;

namespace Magiq.Support.Database {
    public class UpdateExecutor : DynamicSelectQueryExecutor {
        private readonly IPropertySet samplePropertySet;

        public UpdateExecutor(IDatabaseAdapter databaseAdapter, IQueryable where, IEnumerable<IPropertySet> propertySets)
            : base(databaseAdapter, where, propertySets.Cast<IPropertyValueAssignment>(), true) {
            samplePropertySet = propertySets.First();
            Init(samplePropertySet.DeclaringType);
        }

        private void ProcessTypeReferenceBinding() {
            var expression = samplePropertySet.PropertyExpression;
            expression = expression.PreviousExpressionChain(true);
            var typeReferenceExpression = Expression.Property(expression.ChangeParameters(Parameter).Body,
                                                              TypeReferenceProperty.PropertyName);

            Bindings.Add(Expression.Bind(DynamicClass.GetProperty(TypeReferenceName), typeReferenceExpression));
        }

        protected override List<DynamicProperty> CreateDynamicProperties() {
            var properties = base.CreateDynamicProperties();
            properties.Insert(0, new DynamicProperty(TypeReferenceName, TypeReferenceProperty.Type));
            return properties;
        }

        protected override IEnumerable<string> GetCalculatedSqlValues() {
            return base.GetCalculatedSqlValues().Skip(1);
        }

        protected override void OnDynamicClassBuilt() {
            ProcessTypeReferenceBinding();
        }
    }
}